#ifndef GRAPHOPERATION_H_
#define GRAPHOPERATION_H_

#include <boost/shared_ptr.hpp>
#include <boost/random.hpp>
#include <vector>

#include "graphsupport/graph/Graph.h"

// TODO: this class requires careful refactoring
class IOperationSettings
{
public:
	int vertexCount;

	int firstBipart; // TODO: move 2 subclass
	int secondBipart;

	int neighborsBeg;
	int neighborsRange;

	Graph::AdjCoefType cheapBeg;
	Graph::AdjCoefType expensiveBeg;
	double cheapRange;
	double expensiveRange;
	Graph::AdjCoefType facilityPriceBeg;
	Graph::AdjCoefType facilityPriceRange;

	bool triangleIneqEnabled;

public:
	double randomDouble();
	int randomInt( int max );
	void setRandomSeed( int value );

public:
	IOperationSettings( int vertexCount = 0 );
	IOperationSettings( int firstBipart, int secondBipart );
	virtual ~IOperationSettings();

private:
	boost::variate_generator< boost::mt19937, boost::uniform_int<> > sampler;

public:
	static IOperationSettings EMPTY_SETTINGS;
};

class IGraphOperation
{
public:
	IGraphOperation() {}

	virtual void applyTo( Graph & graph, IOperationSettings & genSettings ) = 0;

	virtual ~IGraphOperation();

private:
	IGraphOperation( const IGraphOperation & ) {}
	void operator = ( const IGraphOperation & ) {}
};

typedef boost::shared_ptr< IGraphOperation > IGraphOperationPtr;
typedef std::vector< boost::shared_ptr< IGraphOperation > > IGraphOperationPtrVec;

#endif /* GRAPHOPERATION_H_ */
